import type { ComplianceItem } from '@/types/work'
import type { RemediationItem } from '@/types/Remediation'
// @ts-ignore - xlsx-style has no official typings
import * as XLSX from 'xlsx-js-style'
import * as FileSaver from 'file-saver'
import { HeadingLevel } from 'docx'
import { Document, Packer, Paragraph, TextRun, AlignmentType } from 'docx'
import { RiskLevel, getRiskLevelMap, getComplianceStatusMap } from '@/types/work'
import { RemediationStatus } from '@/types/Remediation'
import type { AssessmentType } from '@/types/business'

// 导出 ComplianceItem 列表为 Excel 文件
export function exportComplianceItemsToExcel(
  items: ComplianceItem[], 
  fileName = '检查项.xlsx', 
  plan_type: AssessmentType = '101',
  includeId: boolean = false
) {
  if (!items || !items.length) return
  console.log("plan_type", plan_type)
  
  // 使用统一的映射配置
  const riskLevelMap = getRiskLevelMap(plan_type)
  const complianceStatusMap = getComplianceStatusMap(plan_type)

  // 按 compliance_type 分组生成 sheet
  const sheetMap: Record<string, ComplianceItem[]> = {}
  items.forEach(item => {
    if (!sheetMap[item.compliance_type]) sheetMap[item.compliance_type] = []
    sheetMap[item.compliance_type].push(item)
  })

  const wb = XLSX.utils.book_new()

  Object.entries(sheetMap).forEach(([type, list]) => {
    const sorted = sortComplianceItems(list)
    // 计算标题最大层级数，用于动态列数
    const maxTitleLevels = Math.max(
      ...list.map(it => (it.title ? it.title.split('#').length : 0))
    )

    const data: any[][] = []
    sorted.forEach(item => {
      const segments = (item.title || '').split('#')
      // 使用 '' 填充不足的层级，保持列数一致
      const paddedSegments = [
        ...segments,
        ...new Array(maxTitleLevels - segments.length).fill('')
      ]

      const opinion = item.compliance_type === 'risk'
        ? (riskLevelMap[item.risk_level ?? 'not-applicable'] ?? '')
        : (complianceStatusMap[item.compliance_status] ?? '')

      const rowData = [
        ...paddedSegments,
        item.description || '',
        item.guide || '',
        item.inspector || '',
        opinion
      ];
      
      // 如果需要包含ID列，在最前面添加ID
      if (includeId) {
        rowData.unshift(item.id);
      }
      
      data.push(rowData);
    })

    const ws = XLSX.utils.aoa_to_sheet(data)

    // 设置列宽 145pt ≈ 200px
    const totalCols = maxTitleLevels + 4 // description, guide, inspector, opinion
    ws['!cols'] = new Array(totalCols).fill({ wpx: 165 })
    // 设置行高 85pt
    ws['!rows'] = data.map(() => ({ hpt: 85 }))

    // 合并评估事项/模块/指标相同的单元格
    const merges: XLSX.Range[] = []
    const mergeCols = Array.from({ length: maxTitleLevels }, (_, idx) => idx)
    mergeCols.forEach(colIdx => {
      let start = 0 // 数据开始行索引
      while (start < data.length) {
        const val = data[start][colIdx]
        let end = start + 1
        while (end < data.length && data[end][colIdx] === val) {
          end++
        }
        if (end - start > 1 && val !== '') {
          merges.push({ s: { r: start, c: colIdx }, e: { r: end - 1, c: colIdx } })
        }
        start = end
      }
    })
    ws['!merges'] = merges

    // 单元格样式：仿宋 14pt，标题行加粗，水平垂直居中，文本自动换行
    Object.keys(ws).forEach(addr => {
      if (addr.startsWith('!')) return
      const cell = ws[addr] as XLSX.CellObject & { s?: any }
      if (!cell.s) cell.s = {}

      cell.s.font = { name: '仿宋', sz: 14 }
      cell.s.alignment = { 
        vertical: 'center', 
        horizontal: 'center',  // 水平居中
        wrapText: true 
      }
    })

    XLSX.utils.book_append_sheet(wb, ws, type)
  })

  const wbout = XLSX.write(wb, { bookType: 'xlsx', type: 'array' })
  FileSaver.saveAs(new Blob([wbout], { type: 'application/octet-stream' }), fileName)
}


/**
 * 导出整改项为Word报告
 * @param items 整改项列表
 * @param fileName 导出文件名，默认为'整改报告.docx'
 */
export function exportRemediationItemsToReport(items: RemediationItem[], fileName = '整改报告') {
  if (!items || !items.length) {
    console.warn('没有可导出的整改项');
    return;
  }
  
  // 深度复制并确保所有项都有有效的文本字段
  const validItems = items.map(item => {
    // 使用try-catch防止意外的序列化错误
    try {
      return {
        ...item,
        id: item.id || '',
        title: typeof item.title === 'string' ? item.title : '无标题',
        description: typeof item.description === 'string' ? item.description : '无内容',
        suggestion: typeof item.suggestion === 'string' ? item.suggestion : '无建议'
      };
    } catch (e) {
      console.error('处理整改项时出错:', e);
      return {
        id: '',
        title: '数据错误',
        description: '数据错误',
        suggestion: '数据错误',
        riskLevel: RiskLevel.LOW,
        status: RemediationStatus.IN_PROGRESS,
        plan_id: '',
        item_id: '',
        createdAt: '',
        updatedAt: ''
      };
    }
  });
  
  // 过滤掉无效项
  const filteredItems = validItems.filter(item => 
    item && typeof item === 'object' && item.id !== undefined
  );
  
  // 创建文档对象
  const doc = new Document({
    sections: [{
      properties: {},
      children: [
        // 标题
        new Paragraph({
          alignment: AlignmentType.CENTER,
          spacing: { after: 400 }, // 段后留白
          children: [new TextRun({ 
            text: '整改报告', 
            bold: true, 
            size: 36, // 三号大小约为18pt
            font: '仿宋'
          })]
        }),
        // 空白行
        new Paragraph({
          children: [new TextRun({ text: '', size: 28, font: '仿宋' })]
        }),
        // 创建文档内容
        ...createRemediationContent(filteredItems)
      ]
    }]
  });

  // 生成文档并保存
  Packer.toBlob(doc).then(blob => {
    FileSaver.saveAs(blob, `${fileName}.docx`);
  });
}

/**
 * 创建整改项文本内容
 */
function createRemediationContent(items: RemediationItem[]): Paragraph[] {
  const paragraphs: Paragraph[] = [];
  
  // 遍历每个整改项创建段落
  for (let i = 0; i < items.length; i++) {
    const item = items[i];
    // 确保所有字段都有值
    const title = typeof item.title === 'string' ? item.title : '无标题';
    const description = typeof item.description === 'string' ? item.description : '无内容';
    const suggestion = typeof item.suggestion === 'string' ? item.suggestion : '无建议';
    const serial_title = title.split("#").pop() || '';  // 最后一个标题

    // 添加项目编号
    const itemNumber = i + 1;
    
    // 评估项标题（一级标题）
    paragraphs.push(
      new Paragraph({
        spacing: { before: 400, after: 200 },  // 增加段前间距
        heading: HeadingLevel.HEADING_1,       // 设置为Word一级标题
        children: [new TextRun({ 
          text: `${itemNumber}. 评估项：${serial_title}`, 
          bold: true, 
          font: '仿宋', 
          size: 32                           // 增大字号
        })]
      })
    );
    
    // 评估项名称（加粗）
    paragraphs.push(
      new Paragraph({
        indent: { left: 480 }, // 缩进1cm（1cm = 480半点）
        spacing: { after: 200 },
        children: [new TextRun({ 
          text: title, 
          bold: true, 
          font: '仿宋', 
          size: 28
        })]
      })
    );
    
    // 评估内容
    paragraphs.push(
      new Paragraph({
        spacing: { after: 200 },
        children: [new TextRun({ 
          text: `评估内容：`, 
          bold: true, 
          font: '仿宋', 
          size: 28
        })]
      })
    );

    paragraphs.push(
      new Paragraph({
        indent: { left: 480 },
        spacing: { after: 200 },
        children: [new TextRun({ 
          text: description, 
          font: '仿宋', 
          size: 28
        })]
      })
    );
    
    // 整改建议
    paragraphs.push(
      new Paragraph({
        spacing: { after: 200 },
        children: [new TextRun({ 
          text: `整改建议：`, 
          bold: true, 
          font: '仿宋', 
          size: 28
        })]
      })
    );

    // 处理整改建议中的换行符（支持 \n、\r\n、\r），每行作为一个段落，并添加黄色背景
    const suggestionLines = suggestion.split(/\r?\n|\r/);
    suggestionLines.forEach((line, index) => {
      paragraphs.push(
        new Paragraph({
          indent: { left: 480 },
          spacing: { after: index === suggestionLines.length - 1 ? 400 : 200 }, // 最后一行段后间距更大
          children: [new TextRun({ 
            text: line || ' ', // 空行用空格代替，避免段落消失
            font: '仿宋', 
            size: 28,
            highlight: 'yellow' // 黄色背景强调
          })]
        })
      );
    });
   
  }
  
  return paragraphs;
}



// 定义可排序对象的最小接口约束
interface SortableItem {
  title: string;
  description: string;
}

/**
 * 根据标题中的层级编号对包含title和description的对象列表进行排序。
 *
 * 标题示例：
 *   - 数字格式: "1.业务应用安全保障#1.1用户管理#1.1.1用户个人普通账号真实性核验"
 *   - 字母格式: "A.业务应用安全保障#A-1用户管理#A-1-1用户个人普通账号真实性核验"
 *   - 混合格式: "A.业务应用安全保障#A1用户管理#A1.1用户个人普通账号真实性核验"
 *
 * 排序规则：
 *   1) 按层级分割（以#为分隔符）
 *   2) 对每一层级，按以下规则比较：
 *      - 先比较字母部分（按字典序）
 *      - 再比较数字部分（按数值大小）
 *   3) 支持任意层级的嵌套比较
 *   4) 如果 title 完全相同，则比较 description 的前5个字符
 */
export function sortComplianceItems<T extends SortableItem>(items: T[]): T[] {
  // 解析段，将混合的字母和数字分开
  // 例如："A-1.2" => [{ type: 'alpha', value: 'A' }, { type: 'num', value: 1 }, { type: 'alpha', value: '.' }, { type: 'num', value: 2 }]
  const parseSegment = (str: string): Array<{ type: 'alpha' | 'num', value: string | number }> => {
    if (!str) return [];
    
    // 匹配字母和数字的混合
    const tokens = str.match(/[a-zA-Z]+|\d+|[^a-zA-Z0-9]+/g) || [];
    return tokens.map(token => {
      const num = parseInt(token, 10);
      return {
        type: isNaN(num) ? 'alpha' : 'num',
        value: isNaN(num) ? token : num
      };
    });
  };

  // 比较两个解析后的段
  const compareParsedSegments = (a: string, b: string): number => {
    const aTokens = parseSegment(a);
    const bTokens = parseSegment(b);
    const len = Math.max(aTokens.length, bTokens.length);

    for (let i = 0; i < len; i++) {
      const aToken = aTokens[i];
      const bToken = bTokens[i];

      // 如果一个已经结束，另一个还有，则短的排在前面
      if (!aToken) return -1;
      if (!bToken) return 1;

      // 类型不同，按类型排序（字母在前，数字在后）
      if (aToken.type !== bToken.type) {
        return aToken.type === 'alpha' ? -1 : 1;
      }

      // 同类型比较
      if (aToken.value !== bToken.value) {
        if (aToken.type === 'num') {
          return (aToken.value as number) - (bToken.value as number);
        } else {
          return String(aToken.value).localeCompare(String(bToken.value));
        }
      }
    }
    return 0;
  };

  // 主排序逻辑
  return [...items].sort((a, b) => {
    // 1. 首先比较 title
    const aParts = a.title.split('#');
    const bParts = b.title.split('#');
    const maxDepth = Math.max(aParts.length, bParts.length);

    for (let i = 0; i < maxDepth; i++) {
      const aPart = aParts[i] || '';
      const bPart = bParts[i] || '';
      
      // 如果某一部分已经可以决定顺序，直接返回结果
      const cmp = compareParsedSegments(aPart, bPart);
      if (cmp !== 0) return cmp;
    }
    
    // 2. 如果 title 完全相同，则比较 description，使用与title相同的比较逻辑
    const aDesc = a.description ? a.description.substring(0, 10) : ''; // 取前10个字符用于比较
    const bDesc = b.description ? b.description.substring(0, 10) : '';
    return compareParsedSegments(aDesc, bDesc);
  });
}

/**
 * 比较两个包含title和description的对象，使用智能排序逻辑
 * @param a 第一个对象
 * @param b 第二个对象
 * @returns 比较结果：-1表社a在前，1表社b在前，0表示相等
 */
export function compareByTitle(
  a: SortableItem, 
  b: SortableItem
): number {
  // 使用sortComplianceItems的排序逻辑进行比较
  const sorted = sortComplianceItems([a, b]);
  return sorted[0] === a ? -1 : 1;
}


export const getBaseURL = () => {
  // 如果是开发环境且有环境变量配置，使用环境变量
  if (import.meta.env.DEV && import.meta.env.VITE_API_BASE_URL) {
    return import.meta.env.VITE_API_BASE_URL;
  }
  // 生产环境或Docker环境使用相对路径
  return '/backend';
};

// 获取评估类型名称
export const getAssessmentTypeName = (type: '101' | '102' | '103' | '104' | '105') => {
  const assessmentTypeMap = {
    '101': '双新评估',
    '102': '涉诈评估',
    '103': '智慧中台评估',
    '104': '5G应用安全评估',
    '105': '数据安全评估'
  };
  return assessmentTypeMap[type] || '未知评估类型';
}

  // 获取评估类型对应的颜色样式
 export const getAssessmentTypeColor = (type: AssessmentType) => {
    const colorMap: Record<AssessmentType, string> = {
      '101': 'bg-blue-100 text-blue-700 border-blue-200',
      '102': 'bg-purple-100 text-purple-700 border-purple-200',
      '103': 'bg-green-100 text-green-700 border-green-200',
      '104': 'bg-orange-100 text-orange-700 border-orange-200',
      '105': 'bg-rose-100 text-rose-700 border-rose-200',
    };
    return colorMap[type] || 'bg-gray-100 text-gray-700 border-gray-200';
  };